module odefu.engine.states.StateMachine;

import odefu.engine.states.State;
import odefu.engine.states.StateQueue;

public class StateMachine
{
	private StateQueue stateQueue;
	
	private State _currentState;
	
	public this()
	{
		stateQueue = new StateQueue();
	}
	
	@property 
	public State currentState()
	{
		return _currentState;
	}
	
	public void update(float delta)
	{
		if (stateQueue.hasStates())
		{
			auto nextState = stateQueue.nextState();
			if ((_currentState && _currentState.allowStateChange(nextState)) || !_currentState)
			{
				switchStates(nextState);
				stateQueue.removeNext();
			}
		}
		if (_currentState)
		{
			_currentState.update(delta);
		}
	}

	public void changeState(State state)
	{
		stateQueue.addState(state);
	}
	
	private void switchStates(State nextState)
	{
		if (_currentState)
		{
			_currentState.exit();
		}
		
		_currentState = nextState;
		_currentState.enter();
	}
}